package com.example.feifei.view.banner;

import android.content.Context;
import android.content.res.TypedArray;
import android.support.annotation.AttrRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.example.feifei.newproject.R;
import com.example.feifei.view.banner.loader.ImageLoaderInterface;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

/**
 * 自定义轮播图
 * Created by feifei on 2017/10/16.
 */

public class Banner extends FrameLayout implements ViewPager.OnPageChangeListener {
    private Context mContext;
    //展示布局
    private int mLayoutResId = R.layout.banner;
    //滑动监听
    private BannerScroller mScroller;
    //标题头
    private List<String> titles;
    //图片展示路径
    private List imageUrls;
    //图片展示布局
    private List<View> imageViews;
    //指示器展示
    private List<ImageView> indicatorImages;
    //用于测量布局
    private DisplayMetrics dm;
    //指示器大小
    private int indicatorSize;
    //指示器的宽高
    private int mIndicatorWidth;
    private int mIndicatorHeight;
    //每个指示器之间的间距
    private int mIndicatorMargin = 5;
    //指示器的选择展示
    private int mIndicatorSelectedResId = R.drawable.gray_radius;
    private int mIndicatorUnselectedResId = R.drawable.white_radius;
    //滑动类型
    private int scaleType = 1;
    //停留时间和滑动事件,在自定义属性里面设置，在此不管用
    private int delayTime = 5000;
    private int scrollTime = 1000;
    //是否自动滑动
    private boolean isAutoPlay = true;
    //标题头背景设置
    private int titleBackground;
    private int titleHeight;
    private int titleTextColor;
    private int titleTextSize;

    private ImageLoaderInterface imageLoader;
    private int bannerStyle = 1;
    private int gravity = -1;

    private int lastPosition = 1;

    //轮播图viewpager
    private BannerViewPager viewPager;
    private LinearLayout indicator, indicatorInside, titleView;
    private TextView bannerTitle, numIndicatorInside, numIndicator;
    //轮播图监听
    private OnBannerListener listener;
    //滑动页数
    private int count = 0;
    //当过展示条目
    private int currentItem;
    //viewapger适配器
    private BannerPagerAdapter adapter;
    //是否滑动
    private boolean isScroll = true;

    private WeakHandler handler = new WeakHandler();

    private ViewPager.OnPageChangeListener mOnPageChangeListener;

    public Banner(Context context) {
        this(context ,null);
    }
    public Banner(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public Banner(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.mContext = context;
        titles = new ArrayList<>();
        imageUrls = new ArrayList<>();
        imageViews = new ArrayList<>();
        indicatorImages = new ArrayList<>();
        dm = context.getResources().getDisplayMetrics();
        indicatorSize = dm.widthPixels / 80;
        initView(context, attrs);
    }
    //初始化视图
    private void initView(Context context, AttributeSet attrs) {
        //初始化时清除之前的布局
        imageViews.clear();
        handleTypedArray(context,attrs);
        View view = LayoutInflater.from(context).inflate(mLayoutResId, this, true);
        viewPager = (BannerViewPager) view.findViewById(R.id.bannerViewPager);
        titleView = (LinearLayout) view.findViewById(R.id.titleView);
        indicator = (LinearLayout) view.findViewById(R.id.circleIndicator);
        indicatorInside = (LinearLayout) view.findViewById(R.id.indicatorInside);
        bannerTitle = (TextView) view.findViewById(R.id.bannerTitle);
        numIndicator = (TextView) view.findViewById(R.id.numIndicator);
        numIndicatorInside = (TextView) view.findViewById(R.id.numIndicatorInside);
        initViewPagerScroll();
    }

    private void initViewPagerScroll() {
        try {
            Field mField = ViewPager.class.getDeclaredField("mScroller");
            mField.setAccessible(true);
            mScroller = new BannerScroller(viewPager.getContext());
            mScroller.setDuration(scrollTime);
            mField.set(viewPager, mScroller);
        } catch (Exception e) {
            Log.e("tag", e.getMessage());
        }
    }

    //设置banner的基本属性
    private void handleTypedArray(Context context, AttributeSet attrs) {
        if (attrs == null) {
            return;
        }
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.Banner);
        mIndicatorWidth = typedArray.getDimensionPixelSize(R.styleable.Banner_indicator_width, indicatorSize);
        mIndicatorHeight = typedArray.getDimensionPixelSize(R.styleable.Banner_indicator_height, indicatorSize);
        mIndicatorMargin = typedArray.getDimensionPixelSize(R.styleable.Banner_indicator_margin, 5);
        mIndicatorSelectedResId = typedArray.getResourceId(R.styleable.Banner_indicator_drawable_selected, R.drawable.gray_radius);
        mIndicatorUnselectedResId = typedArray.getResourceId(R.styleable.Banner_indicator_drawable_unselected, R.drawable.white_radius);
        scaleType = typedArray.getInt(R.styleable.Banner_image_scale_type, scaleType);
        delayTime = typedArray.getInt(R.styleable.Banner_delay_time, 3000);
        scrollTime = typedArray.getInt(R.styleable.Banner_scroll_time, 1000);
        isAutoPlay = typedArray.getBoolean(R.styleable.Banner_is_auto_play, true);
        titleBackground = typedArray.getColor(R.styleable.Banner_title_background, -1);
        titleHeight = typedArray.getDimensionPixelSize(R.styleable.Banner_title_height, -1);
        titleTextColor = typedArray.getColor(R.styleable.Banner_title_textcolor, -1);
        titleTextSize = typedArray.getDimensionPixelSize(R.styleable.Banner_title_textsize, -1);
        mLayoutResId = typedArray.getResourceId(R.styleable.Banner_layout_id, mLayoutResId);
        typedArray.recycle();
    }

    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        if (mOnPageChangeListener != null) {
            mOnPageChangeListener.onPageScrolled(position, positionOffset, positionOffsetPixels);
        }
    }

    @Override
    public void onPageSelected(int position) {
        if (mOnPageChangeListener != null) {
            mOnPageChangeListener.onPageSelected(position);
        }
//        if (bannerStyle == BannerConfig.CIRCLE_INDICATOR ||
//                bannerStyle == BannerConfig.CIRCLE_INDICATOR_TITLE ||
//                bannerStyle == BannerConfig.CIRCLE_INDICATOR_TITLE_INSIDE) {
            indicatorImages.get((lastPosition - 1 + count) % count).setImageResource(mIndicatorUnselectedResId);
            indicatorImages.get((position - 1 + count) % count).setImageResource(mIndicatorSelectedResId);
            lastPosition = position;
//        }
        if (position == 0) position = count;
        if (position > count) position = 1;
    }

    @Override
    public void onPageScrollStateChanged(int state) {
        if (mOnPageChangeListener != null) {
            mOnPageChangeListener.onPageScrollStateChanged(state);
        }
        currentItem = viewPager.getCurrentItem();
        switch (state) {
            case 0://No operation
                if (currentItem == 0) {
                    viewPager.setCurrentItem(count, false);
                } else if (currentItem == count + 1) {
                    viewPager.setCurrentItem(1, false);
                }
                break;
            case 1://start Sliding
                if (currentItem == count + 1) {
                    viewPager.setCurrentItem(1, false);
                } else if (currentItem == 0) {
                    viewPager.setCurrentItem(count, false);
                }
                break;
            case 2://end Sliding
                break;
        }

    }
    //设置标题背景,指示器类型不同
    private void setTitleStyleUI() {
        if (titles.size() != imageUrls.size()) {
            throw new RuntimeException("[Banner] --> The number of titles and images is different");
        }
        if (titleBackground != -1) {
            titleView.setBackgroundColor(titleBackground);
        }
        if (titleHeight != -1) {
            titleView.setLayoutParams(new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, titleHeight));
        }
        if (titleTextColor != -1) {
            bannerTitle.setTextColor(titleTextColor);
        }
        if (titleTextSize != -1) {
            bannerTitle.setTextSize(TypedValue.COMPLEX_UNIT_PX, titleTextSize);
        }
        if (titles != null && titles.size() > 0) {
            bannerTitle.setText(titles.get(0));
            bannerTitle.setVisibility(View.VISIBLE);
            titleView.setVisibility(View.VISIBLE);
        }
    }
    //设置图片展示
    private void setImageList(List<?> imagesUrl) {
        if (imagesUrl == null || imagesUrl.size() <= 0) {
            Log.e("tag", "Please set the images data.");
            return;
        }
        initImages();
        for (int i = 0; i <= count + 1; i++) {
            View imageView = null;
            if (imageLoader != null) {
                imageView = imageLoader.createImageView(mContext);
            }
            if (imageView == null) {
                imageView = new ImageView(mContext);
            }
            //设置imageView的截取方式
            ImageView view = (ImageView) imageView;
            view.setScaleType(ImageView.ScaleType.CENTER_CROP);

            Object url = null;
            if (i == 0) {
                url = imagesUrl.get(count - 1);
            } else if (i == count + 1) {
                url = imagesUrl.get(0);
            } else {
                url = imagesUrl.get(i - 1);
            }
            imageViews.add(imageView);
            if (imageLoader != null)
                imageLoader.displayImage(mContext, url, imageView);
            else
                Log.e("tag", "Please set images loader.");
        }
    }
    //初始化指示器展示类型
    private void initImages() {
        imageViews.clear();
            createIndicator();
//        } else if (bannerStyle == BannerConfig.NUM_INDICATOR_TITLE) {
//            numIndicatorInside.setText("1/" + count);
//        } else if (bannerStyle == BannerConfig.NUM_INDICATOR) {
//            numIndicator.setText("1/" + count);
//        }
    }
    //指示器添加
    private void createIndicator() {
        indicatorImages.clear();
        indicator.removeAllViews();
        indicatorInside.removeAllViews();
        for (int i = 0; i < count; i++) {
            ImageView imageView = new ImageView(mContext);
            imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(mIndicatorWidth, mIndicatorHeight);
            params.leftMargin = mIndicatorMargin;
            params.rightMargin = mIndicatorMargin;
            if (i == 0) {
                imageView.setImageResource(mIndicatorSelectedResId);
            } else {
                imageView.setImageResource(mIndicatorUnselectedResId);
            }
            indicatorImages.add(imageView);
//            if (bannerStyle == BannerConfig.CIRCLE_INDICATOR ||
//                    bannerStyle == BannerConfig.CIRCLE_INDICATOR_TITLE)
            indicator.addView(imageView, params);
//            else if (bannerStyle == BannerConfig.CIRCLE_INDICATOR_TITLE_INSIDE)
//                indicatorInside.addView(imageView, params);
        }
    }
    //设置数据
    private void setData() {
        currentItem = 1;
        if (adapter == null) {
            adapter = new BannerPagerAdapter();
            viewPager.addOnPageChangeListener(this);
        }
        viewPager.setAdapter(adapter);
        viewPager.setFocusable(true);
        viewPager.setCurrentItem(1);
        if (gravity != -1)
            indicator.setGravity(gravity);
        if (isScroll && count > 1) {
            viewPager.setScrollable(true);
        } else {
            viewPager.setScrollable(false);
        }
        if (isAutoPlay){
            startAutoPlay();
        }
    }
    //计时轮播
    public void startAutoPlay() {
        handler.removeCallbacks(task);
        handler.postDelayed(task, delayTime);
    }

    private final Runnable task = new Runnable() {
        @Override
        public void run() {
            if (count > 1 && isAutoPlay) {
                currentItem = currentItem % (count + 1) + 1;
//                Log.i(tag, "curr:" + currentItem + " count:" + count);
                if (currentItem == 1) {
                    viewPager.setCurrentItem(currentItem, false);
                    handler.post(task);
                } else {
                    viewPager.setCurrentItem(currentItem);
                    handler.postDelayed(task, delayTime);
                }
            }
        }
    };
    //适配器
    class BannerPagerAdapter extends PagerAdapter {

        @Override
        public int getCount() {
            return imageViews.size();
        }

        @Override
        public boolean isViewFromObject(View view, Object object) {
            return view == object;
        }

        @Override
        public Object instantiateItem(ViewGroup container, final int position) {
            container.addView(imageViews.get(position));
            View view = imageViews.get(position);
            if (listener != null) {
                view.setOnClickListener(new OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        listener.OnBannerClick(toRealPosition(position));
                    }
                });
            }
            return view;
        }

        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            container.removeView((View) object);
        }
        /**
         * 返回真实的位置
         *
         * @param position
         * @return 下标从0开始
         */
        public int toRealPosition(int position) {
            int realPosition = (position - 1) % count;
            if (realPosition < 0)
                realPosition += count;
            return realPosition;
        }

    }

    public void setOnPageChangeListener(ViewPager.OnPageChangeListener onPageChangeListener) {
        mOnPageChangeListener = onPageChangeListener;
    }

    //设置图片名称
    public Banner setImages(List<?> imageUrls) {
        this.imageUrls = imageUrls;
        this.count = imageUrls.size();
        return this;
    }
    //图片加载方式
    public Banner setImageLoader(ImageLoaderInterface imageLoader) {
        this.imageLoader = imageLoader;
        return this;
    }
    /**
     * 废弃了旧版接口，新版的接口下标是从1开始，同时解决下标越界问题
     *
     * @param listener
     * @return
     */
    public Banner setOnBannerListener(OnBannerListener listener) {
        this.listener = listener;
        return this;
    }
    //开始进行轮播
    public Banner start() {
        setBannerStyleUI();
        setImageList(imageUrls);
        setData();
        return this;
    }
    //设置下方指示器展示
    private void setBannerStyleUI() {
        int visibility;
        if (count > 1) {
            visibility = View.VISIBLE;
        }else{
            visibility = View.GONE;
        }
        indicator.setVisibility(visibility);
        //TODO
//        setTitleStyleUI();
    }

    public void stopAutoPlay() {
        handler.removeCallbacks(task);
    }
}
